

#include <vfs.h>
#include <fs/fileinfo.h>
#include <asset/reader/assetreadershader.h>
#include <gfx/ishader.h>
#include <stdio.h>

ceAssetReaderShader::ceAssetReaderShader()
{
	CE_OBJECT_CONSTR
}




bool ceAssetReaderShader::CanRead(ceEngine *engine, ceAssetTypeID type, const ceAssetLocator &locator)
{
	if (type != iShader::AssetTypeID)
		{
			return false;
		}


	ceFileInfo info (locator.GetLocation());

	std::string ext = info.GetExtension();

	return  ext == "vert"
			||  ext == "frag"
			||  ext == "geom"
			||  ext == "vs"
			||  ext == "fs"
			||	ext == "gs";
}

ceRef<ceAsset> ceAssetReaderShader::Read(ceEngine *engine, ceAssetTypeID type, const ceAssetLocator &locator)
{
	iFile *file = ceVFS::Get()->Open(locator.GetLocation(), OM_Read, TM_Binary);
	ceReleasePtr<iFile> releaseFile (file);
	if (!file)
		{
			return 0;
		}


	ceFileInfo info (locator.GetLocation());
	std::string ext = info.GetExtension();
	ceShaderType shaderType = ST_Vertex;
	if (ext == std::string("vert") || ext == std::string ("vs"))
		{
			shaderType = ST_Vertex;
		}
	else if (ext == std::string ("frag") || ext == std::string ("fs"))
		{
			shaderType = ST_Fragment;
		}
	else if (ext == std::string ("geom") || ext == std::string ("gs"))
		{
			shaderType = ST_Geometry;
		}
	else
		{
			return 0;
		}

	file->Seek(SP_End, 0);
	long size = file->Tell();
	file->Seek(SP_Set, 0);

	char* source = new char[size+1];
	file->Read(source, size);
	file->Close();
	source[size] = '\0';

	iDevice* device = engine->GetDevice();
	iShader* shader = device->CreateShader(shaderType);
	if (!shader)
		{
			delete [] source;
			return 0;
		}
  shader->SetLocator(locator);

	shader->SetSource(source);

  bool compileSuccess = shader->Compile();
  delete [] source;

  if (!compileSuccess)
		{
			printf ("Unable to compile shader: %s @ %s\n", locator.GetName(), locator.GetLocation());
			printf ("%s\n", (const char*)shader->GetCompileInfoLog().c_str());
			shader->Release();
      return 0;
		}

	return shader;

}
